#lang errortrace racket
(require "hw5-util.rkt")

(define first-frame-eff (heap-alloc empty-heap root-frame))
(define root-mem (eff-state first-frame-eff))
(define root-environ (eff-result first-frame-eff))

(define (environ-put mem env var val)
  (define frm (heap-get mem env))
  (define new-frm (frame-put frm var val))
  (heap-put mem env new-frm))


(define (environ-push mem env var val)
  (define new-frm (frame-push env var val))
  (heap-alloc mem new-frm))

(define mem1
    (environ-put root-mem root-environ
      (d:variable 'x) (d:number 3)))
(define mem2
   (environ-put mem1 root-environ
      (d:variable 'y) (d:number 5)))

(define mem3+e1
    (environ-push mem2 root-environ
        (d:variable 'z) (d:number 6)))
(define mem3 (eff-state mem3+e1))
(define e1 (eff-result mem3+e1))
(define mem4 (environ-put mem3 e1
  (d:variable 'x) (d:number 7)))

(define mem5+e2
  (environ-push mem4 root-environ (d:variable 'm) (d:number 1)))
(define mem5 (eff-state mem5+e2))
(define e2 (eff-result mem5+e2))
(define mem6 (environ-put mem5 e2
  (d:variable 'y) (d:number 2)))

(quote-mem mem6)

(define (environ-get mem env var)
  (define frm (heap-get mem env))
  (define res (frame-get frm var))
  (cond [res res]
        [(frame-parent frm) (environ-get mem (frame-parent frm) var)]
        [else (error (format "Variable undefined: ~a" (d:variable-name var)))]))


;(environ-get mem6 e2 (d:variable 'm))
;(environ-get mem6 e2 (d:variable 'x))
;(environ-get mem6 e1 (d:variable 'y))
;(environ-get mem6 e1 (d:variable 'x))
(environ-get mem6 e1 (d:variable 'foo))




;